package com.hongyi.app.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.hongyi.app.entity.Role;
import com.hongyi.app.entity.RolePermission;
import com.hongyi.app.entity.User;
import com.hongyi.app.mapper.PermissionMapper;
import com.hongyi.app.mapper.RoleMapper;
import com.hongyi.app.mapper.RolePermissionMapper;
import com.hongyi.app.mapper.UserMapper;
import com.hongyi.app.service.RoleService;
import lombok.Data;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

/**
 * @author HongYi
 */
@Slf4j
@Data
public class RoleServiceImpl implements RoleService {
    private RoleMapper roleMapper;
    private RolePermissionMapper rolePermissionMapper;
    private PermissionMapper permissionMapper;
    private UserMapper userMapper;

    @Override
    public List<Role> list() {

        List<Role> roles = roleMapper.list();

        return roles != null ? roles : new ArrayList<>();
    }

    @Override
    public boolean checkTitle(String title) {

        return roleMapper.selectByTitle(title) != null;
    }

    @Override
    public Role selectById(Integer id) {
        Role role = roleMapper.selectById(id);

        return role != null ? role : new Role();
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public int insert(Role role, Integer[] permissionIds) {

        if (permissionIds.length < 0) {
            log.warn("权限不能为空");
            return 0;
        }

        if (roleMapper.insert(role) <= 0) {
            log.warn("role表增加角色记录失败，事务回滚···");
            return 0;
        }

        Integer roleId = role.getId();
        grantPermissionForRole(roleId, permissionIds);

        return 1;

    }

    /*业务描述：先修改角色的基本信息，再删除该角色的全部中间表记录，最后循环为角色赋予新权限*/

    @Transactional(rollbackFor = Exception.class)
    @Override
    public int updateById(Role role, Integer[] permissionIds) {

        if (permissionIds.length <=0) {
            log.warn("权限不能为空");
            return 0;
        }

       if( roleMapper.updateById(role)<=0){
           throw new RuntimeException("role表记录修改失败");

       }
         Integer roleId = role.getId();
       if(rolePermissionMapper.deleteByRoleId(roleId)<=0){
           throw new RuntimeException("rolePermission中间表记录删除失败");
       }

       grantPermissionForRole(roleId,permissionIds);

        return 1;

    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public int deleteById(Integer id) {
        //角色被使用、或者角色不存在时，角色记录不能删除
        /*selectById联查了user表，当角色没被赋予用户时，用上述方法差不多role记录*/
        Role role =roleMapper.selectByIdg(id);
        log.info("{}",role);
        if(role == null ){

            log.info("角色不存在，返会0···");
            return 0;
        }
        if (rolePermissionMapper.deleteByRoleId(id)<=0){
            throw new RuntimeException("中间表记录删除失败，事务回滚···");
        }
        if(roleMapper.deleteById(id)<=0){
            throw new RuntimeException("至少有一条role记录不存在，删除role表记录失败，事务回滚···");
        }

        return 1;
    }


    /*先检查角色是否正被使用，再删除中间表记录，最后删除角色基本信息*/

    @Override
    public int deleteByIds(Integer[] ids) {

        if (ids.length <=0) {
            log.warn("id不能为空");
            return 0;
        }
    //角色被使用、或者角色不存在时，角色记录不能删除
      List<Role> roles = roleMapper.selectByIds(ids);
        if(roles.size()<ids.length){
            log.info("至少1条角色记录不存在，删除失败，返回0");
            return 0;
        }

        for (Role role : roles) {
           if(role.getUsers() !=null){
                log.info("至少有一个角色被使用，删除失败，返回0···");
                return 0;
            }
        }

        //删除中间表记录
        if(rolePermissionMapper.delectByRoleIds(ids)<=0){
            throw  new RuntimeException("中间表记录删除失败，事务回滚···");
        }

        if(roleMapper.delectByIds(ids)<ids.length){
            throw new RuntimeException("至少有一条role记录不存在，删除role表记录失败，事务回滚···");
        }

        return 1;
    }

    @Override
    public PageInfo<Role> paging(Integer num, Integer size) {
        PageHelper.startPage(num,size);
        List<Role> list = roleMapper.list();
        if(list != null ){
            return  new PageInfo<>(list);
        }

        return new PageInfo<>();
    }


    /**
     * 给角色赋权函数
     * @param roleId role表主键
     * @param permissionIds permission表主键数组
     */
    @Transactional(rollbackFor = Exception.class)
    public void grantPermissionForRole(Integer roleId, Integer[] permissionIds) {
        for (Integer permissionId : permissionIds) {
            RolePermission rolePermission = new RolePermission();
            rolePermission.setRoleId(roleId);
            rolePermission.setPermissionId(permissionId);

            if (rolePermissionMapper.insert(rolePermission) <= 0) {
                throw new RuntimeException("rolePermission表增加记录失败，事务回滚···");
            }
        }
    }

}

